<?php

namespace App\Models\Traits;

use Carbon\Carbon;
use App\Models\GoldRecord;
use Brick\Math\RoundingMode;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Illuminate\Database\Eloquent\Builder;

trait HasUserGoldRecord
{
    public static function stormClickCacheKey(): string
    {
        return "user_storm_clicks";
    }

    public function myStormClickCacheKey(): string
    {
        return "user_{$this->id}_storm_clicks";
    }

    public function setStormClick()
    {
        //Redis::transaction(function () {
            Redis::incr($this->myStormClickCacheKey());
            $clicks = Redis::get("user_{$this->id}_storm_clicks");
            Redis::zAdd(self::stormClickCacheKey(), $clicks, "{$this->id}_{$this->name}");
        //});
    }

    public static function getStormClick()
    {
        return Redis::zRevRangeByScore(self::stormClickCacheKey(), 100000, 100, 'withscores');
    }

	public function hasValidGoldRecord(): bool
	{
		return $this->goldRecords()->whereNotNull('paid_at')->exists();
	}

	public function hasValidGoldRecordYesterday(): bool
	{
		return $this->goldRecords()->whereNotNull('paid_at')->whereDate("created_at",Carbon::yesterday())->exists();
	}

	public function hasNoValidGoldRecord(): bool
	{
		return !$this->hasValidGoldRecord();
	}

	public function hasGoldBeanSupport(): bool
	{
        $createdAt = Carbon::today()->year(2022)->month(7)->day(20);

		if (! cs('storm')->is_gold_support_open) {
            return false;
        } elseif (cs('storm')->gold_support_beans <= 0) {
            return false;
        } elseif ($this->created_at->lt($createdAt)) {
            return false;
        } elseif (!$this->parent) {
            return false;
        } elseif ($this->goldBeans()->exists()) {
			return false;
		} elseif ($this->hadSupportedGoldBeans()) {
			return false;
		} else {
			return true;
		}
	}

	public function hasGoldCoinSupport(): bool
	{
        $createdAt = Carbon::today()->year(2022)->month(7)->day(20);

		if (! cs('storm')->is_gold_support_open) {
            return false;
        } elseif (cs('storm')->gold_support_coins <= 0) {
            return false;
        } elseif (!$this->parent) {
            return false;
        } elseif ($this->created_at->lt($createdAt)) {
            return false;
        } elseif ($this->goldCoins()->exists()) {
			return false;
		} elseif ($this->hadSupportedGoldCoins()) {
			return false;
		} else {
			return true;
		}
	}

	public function hasGoldCashSupport(): bool
	{
        $createdAt = Carbon::today()->year(2022)->month(7)->day(20);

		if (! cs('storm')->is_gold_support_open) {
            return false;
        } elseif (cs('storm')->gold_support_cashes <= 0) {
            return false;
        } elseif ($this->created_at->lt($createdAt)) {
            return false;
        } elseif (!$this->parent) {
            return false;
        } elseif ($this->goldCoins()->exists()) {
			return false;
		} elseif ($this->hadSupportedGoldCoins()) {
			return false;
		} else {
			return true;
		}
	}

    public function hasGoldSupport(): bool
    {
        return $this->hasGoldBeanSupport()
            and $this->hasGoldCoinSupport()
            and $this->hasGoldCashSupport();
    }

    public function hadGoldSupport(): bool
    {
        return $this->hadSupportedGoldBeans()
            and $this->hadSupportedGoldCoins()
            and $this->hadSupportedGoldCashes();
    }

	public function myGoldWastesMoney()
	{
		return $this->goldRecords()
			->whereDate('created_at', Carbon::yesterday())
			->whereNotNull('paid_at')
			->whereNull('closed_at')
			->sum('record_price');
	}

    public function isYesterdayJoined($rid = null): bool
    {
        if ($rid) {
            return $this->goldRecords()
                ->whereDate('created_at', Carbon::yesterday())
                ->where('gold_round_id', $rid)
                ->exists();
        }

        return $this->goldRecords()
            ->whereDate('created_at', Carbon::yesterday())
            ->exists();
    }

	public function myGoldRecordsMoneyToday()
	{
		return $this->goldRecords()
			->whereDate('created_at', Carbon::yesterday())
			->whereNotNull('paid_at')
			->whereNull('closed_at')
			->sum('record_price');
	}

    public function myGoldRecordsChildrenCount(): int
    {
        return $this->children()
            ->whereHas('goldRecords', function (Builder $query) {
                $query->whereNotNull('paid_at');
            })->count();
    }

	public function stormDirectPrizeMoneyToday(GoldRecord $record)
	{
		$internPercent = big_decimal(cs('storm')->child_record_give_direct_parent_intern_prize_percent);
		$masterPercent = big_decimal(cs('storm')->child_record_give_direct_parent_master_prize_percent);

		if ($internPercent->isLessThanOrEqualTo(0)
            and $masterPercent->isLessThanOrEqualTo(0)) {
            return big_decimal(0);
        }

		 return big_decimal($record->pay_net_price)
                ->multipliedBy($masterPercent->multipliedBy(0.01))
                ->toScale(2, RoundingMode::HALF_UP);
	}

	public function totalGoldRecordPrice()
	{
		return $this->goldRecords()->whereNotNull('paid_at')->whereNull('closed_at')->sum('pay_net_price');
	}

	public function childrenGoldRecordCount()
	{
		$joinSql =  "(select sum(pay_net_price) as today_record_price,count(id) as today_record_count,user_id from gold_records where paid_at != '' group by user_id ) AS `r` ";

		if($this->children()){

			return  $this->children()->join(DB::Raw($joinSql),'r.user_id','=','users.id')->count();
		}else{

			return 0;
		}
		
	}

	public function resoldProfitAll()
	{
		$sum = $this->goldRecords()->whereNotNull('paid_at')->where("finished_at",'<',Carbon::today()->toDateTimeString())->sum("record_all_price");
		if($sum){

			return big_decimal($sum)
                ->multipliedBy(0.02)
                ->toScale(2, RoundingMode::HALF_UP);		
        }

		return '0.00';
	}

	public function resoldProfitYesterday()
	{
		$sum = $this->goldRecords()->whereNotNull('paid_at')->whereDate("finished_at",Carbon::yesterday())->sum("record_all_price");
		if($sum){

			return big_decimal($sum)
                ->multipliedBy(0.02)
                ->toScale(2, RoundingMode::HALF_UP);		
        }

		return '0.00';
	}
}
